#ifndef SES_ALARM_CLOCK_H
#define SES_ALARM_CLOCK_H

/*INCLUDES *******************************************************************/
#include "ses_scheduler.h"
#include "ses_buzzer.h"
#include "ses_button.h"
#include "ses_display_print.h"
#include "ses_common.h"


/* TYPES *********************************************************************/
typedef struct Event Event;
typedef struct Fsm Fsm;

typedef void (*State)(Fsm *, const Event *);

struct Fsm{
	State state;
	uint8_t alarmSet; // is alarm enabled ?
	uint32_t timeSet; // temporary buffer for time
};

struct Event{
	uint8_t signal;
};


/* DEFINES & MACROS **********************************************************/
/**
 * Signals used by the alarm clock FSM
 */
enum {JS_BUTTON, ROT_BUTTON, SECOND_TIMER, ALARM_TIMER, NULL_EVENT};


/* FUNCTION PROTOTYPES *******************************************************/
/**
 * Dispatches events to state machine, called in application
 */
inline static void aClock_dispatch(Fsm* fsm, const Event *event){
	fsm->state(fsm, event);
}

/**
 * Initialize the state mashine with all needed functions.
 *
 * @param fsm	pointer to used state mashine
 */
void aClock_init(Fsm *fsm);


/**
 * From here the hours of the clock can be set.
 *
 * @param fsm	pointer to used state mashine
 * @param event	ROT-BUTTON, JS-BUTTON
 */
void aClock_setHH(Fsm *fsm, const Event *event);


/**
 * From here the minutes of the clock can be set.
 *
 * @param fsm	pointer to used state mashine
 * @param event	ROT-BUTTON, JS-BUTTON
 */
void aClock_setMM(Fsm *fsm, const Event *event);


/**
 * The normal operation state, displays the time HH:MM:SS and flashes green led.
 * Possible to go to alarm or set alarm state.
 *
 * @param fsm	pointer to used state mashine
 * @param event	ROT-BUTTON, JS-BUTTON, SECOND_TIMER
 */
void aClock_normalMode(Fsm *fsm, const Event *event);


/**
 * The alarm state is like the normal operation, but is switching to
 * buzzing state in case the time matches the set alarm time.
 *
 * @param fsm	pointer to used state mashine
 * @param event	ROT-BUTTON, SECOND_TIMER, ALARM_TIMER
 */
void aClock_alarmMode(Fsm *fsm, const Event *event);


/**
 * Set the HH of the alarm time
 *
 * @param fsm	pointer to used state mashine
 * @param event	ROT-BUTTON, JS-BUTTON
 */
void aClock_setAlarmHH(Fsm *fsm, const Event *event);


/**
 * Set the MM of the alarm time
 *
 * @param fsm	pointer to used state mashine
 * @param event	ROT-BUTTON, JS-BUTTON
 */
void aClock_setAlarmMM(Fsm *fsm, const Event *event);


/**
 * Make some sound and flash the red led.
 * Any key pressed, stops the buzzing and returns to normal state.
 *
 * @param fsm	pointer to used state mashine
 * @param event	ROT-BUTTON, JS-BUTTON
 */
void aClock_buzzing(Fsm *fsm, const Event *event);

#endif
